package gw.com.android.presenter.http;

import android.os.Looper;
import android.text.TextUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import gw.com.android.app.GTConfig;
import gw.com.android.model.ConfigType;
import gw.com.android.model.ConfigUtil;
import okhttp3.Request;
import okhttp3.Response;
import www.com.library.app.Logger;

/**
 * @author jett
 * @since 2018-01-11.
 */
public class ChatTokenRequest {

    private final String TAG = "ChatTokenRequest";
    private final String PREF_TOKEN = "pref_jiepan_token";

    public String acquire() {
        if (Looper.getMainLooper() == Looper.myLooper()) {
            throw new IllegalStateException("ChatTokenRequest prohibit to acquire token in main thread");
        }
        String token = fetchLocalToken();
        if (TextUtils.isEmpty(token)) {
            Logger.i(TAG, "local token is empty..");
            token = requestToken();
        }
        return token;
    }

    public void acquire(final OnTokenListener listener) {
        String token = fetchLocalToken();
        if (!TextUtils.isEmpty(token)) {
            if (listener != null) {
                listener.onSuccess(token);
            }
            return;
        }
        final String tokenUrl = ConfigUtil.instance().getHttpUrlIp(ConfigType.CHAT_URL_TAG) + "/api/token/getToken";
        new Https().url(tokenUrl)
                .addParam("appId", ConfigUtil.instance().mConfigObject.optString(ConfigType.CHAT_APPID))
                .addParam("appSecret", ConfigUtil.instance().mConfigObject.optString(ConfigType.CHAT_APPSECRET))
                .responseOnUiThread(true)
                .post(new Https.ResponseCallback<String>() {
                    @Override
                    public void onSuccess(Request request, Response response, String result, int code) {
                        String token = null;
                        if (!TextUtils.isEmpty(result)) {
                            try {
                                JSONObject json = new JSONObject(result);
                                token = json.optString("token");
                                int expires = json.optInt("expires");
                                storeToken(token, expires);
                            } catch (JSONException e) {
                                if (listener != null) {
                                    listener.onFailure(e);
                                }
                                return;
                            }
                        }
                        if (listener != null) {
                            listener.onSuccess(token);
                        }
                    }

                    @Override
                    public void onFailure(Request request, IOException e) {
                        if (listener != null) {
                            listener.onFailure(e);
                        }
                    }
                });
    }

    public interface OnTokenListener {

        void onSuccess(String token);

        void onFailure(Exception e);

    }

    private String fetchLocalToken() {
        String value = GTConfig.instance().getStringValue(PREF_TOKEN);
        if (!TextUtils.isEmpty(value)) {
            String[] split = value.split("::");
            if (split.length >= 2) {
                String token = split[0];
                String time = split[1];
                long expire = Long.parseLong(time);
                if (System.currentTimeMillis() >= expire) {
                    GTConfig.instance().setStringValue(PREF_TOKEN, null);
                } else {
                    return token;
                }
            }
        }
        return null;
    }

    private void storeToken(String token, int expireHours) {
        if (TextUtils.isEmpty(token) || expireHours <= 0) {
            GTConfig.instance().setStringValue(PREF_TOKEN, null);
            Logger.i(TAG, "clear local token");
            return;
        }
        long expireTime = expireHours * 60 * 60 * 1000 + System.currentTimeMillis();
        String value = token + "::" + expireTime;
        GTConfig.instance().setStringValue(PREF_TOKEN, value);
        Logger.i(TAG, "token was stored to local");
    }

    private String requestToken() {
        final String tokenUrl = ConfigUtil.instance().getHttpUrlIp(ConfigType.CHAT_URL_TAG) + "/api/token/getToken";
        try {
            Response response = new Https().url(tokenUrl)
                    .addParam("appId", ConfigUtil.instance().mConfigObject.optString(ConfigType.CHAT_APPID))
                    .addParam("appSecret", ConfigUtil.instance().mConfigObject.optString(ConfigType.CHAT_APPSECRET))
                    .post();
            if (response != null && response.isSuccessful()) {
                String str = response.body().string();
                JSONObject json = new JSONObject(str);
                String token = json.optString("token");
                int expires = json.optInt("expires");
                storeToken(token, expires);
                return token;
            }
        } catch (Exception e) {
            Logger.e(TAG, e);
        }
        return null;
    }

    public void clearLocalToken() {
        storeToken(null, 0);
    }

}
